<?php

namespace doumiaoduo\payment;

use common\components\extenders\RequestManage;
use common\components\helpers\Fun;
use yii\BaseYii;
use doumiaoduo\payment\bin\InterfacePayment;

class Wechat extends  \doumiaoduo\payment\bin\Payment implements InterfacePayment
{
    /**
     *  统一下单接口
     */
    const UNIFIEDORDER = 'https://api.mch.weixin.qq.com/pay/unifiedorder';

    /**
     * 证书cart
     */
    const SSLCERT_PATH = '';
    /**
     * 证书 key
     */
    const SSLKEY_PATH = '';

    /**
     * KEY
     */
    const KEY = 'M9jJ2FE6d4CIKbb9F3F7bCFjJkmJjEKk';

    /**
     * @var string 支付方式名称
     */
    public $name = '微信支付';
    /**
     * @var string 支付方式接口名称
     */
    public $app_name = '微信支付接口';
    /**
     * @var string 支付方式key
     */
    public $app_key = 'Wechat';

    /**
     * @var string 统一显示的名称
     */
    public $display_name = '微信支付';
    /**
     * @var string 当前支付方式所支持的平台
     */
    public $platform = 'wap';

    /**
     * @var string 当前支付方式的版本号
     */
    public $version = '1.0';

    /**
     * @var 作者
     */
    public $author = '豆苗朵';

    /**
     * @param 是否货到付款
     */
    public $is_cod = 0;

    /**
     * @var string 交易类型
     */
    public $trade_type;

    /**
     * @var boolean 是否使用证书
     */
    public $useCert = false;

    /**
     * @param string $platform
     */
    public  $nonce_str;

    /**
     * @param string $platform
     */
    public  $ip;


    public function __construct($platform = 'wap'){
        $this->method = 'POST';
        $this->submit_charset = 'utf-8';
        if($this->platform == 'wap'){
            $this->callback_url = 'http://wechat.dmiaod.com/payment/notify';
            $this->trade_type = 'JSAPI';
        }else{
            $this->callback_url = 'doumiaoduo/pc';
            $this->trade_type = 'NATIVE';
        }
        $this->nonce_str = $this->createNoncestr();
        $this->ip = (new RequestManage())->getUserIP();

        parent::__construct($this->method,$this->submit_url);

    }

    /**
     *  描述
     */

    public function intro(){
        return '微信支付是集成在微信客户端的支付功能，用户可以通过手机完成快速的支付流程。微信支付以绑定银行卡的快捷支付为基础，向用户提供安全、快捷、高效的支付服务。';

    }


    public function setting(){

        return [
            'appid' =>[
                'title' =>  \Yii::t('common','公众账号ID'),
                'type'  => 'string',
                'validate_type' => 'required',
            ],
            'pay_brief' => [
                'title' => \Yii::t('common','商户号'),
                'type'  => 'string',
            ]
        ];
    }

    /**
     *
     * @params array - 提交订单信息
     * @return html - 自动提交的表单
     */
    public function dopay($order){
        $this->add_field('appid','wx288b2b74fdad1dbe');//设置公众账号ID
        $this->add_field('mch_id','1290331201'); //设置商户号
        $this->add_field('nonce_str',$this->nonce_str);//随机32位字符
        $this->add_field('device_info','WEB');
        $this->add_field('trade_type',$this->trade_type);
        $this->add_field('body',$order['name']);
        $this->add_field('out_trade_no',$order['sn']);
        $this->add_field('total_fee',$order['final_amount']);
        $this->add_field('spbill_create_ip',$this->ip);
        $this->add_field('trade_type','JSAPI');
        $this->add_field('product_id','444');
        $this->add_field('notify_url',$this->callback_url);
        $this->add_field('openid',$order['openid']);
        $this->add_field('sign',$this->GetSign($this->fields));//签名
        //$this->getOpenId();

        $xmlParam = $this->arrayToXml();
        $result = $this->PostXmlCurl($xmlParam);
        //print_r($result);die;
        if($this->platform == 'wap'){
            $arr = $this->xmlToArray($result);
            $t = time();
            $signArr = [
                'appId' => $arr['appid'],
                'timeStamp' =>"$t",
                'nonceStr'  =>$arr['nonce_str'],
                'package'  => 'prepay_id='.$arr['prepay_id'],
                'signType' =>'MD5'
            ];
            $signArr['paySign'] = $this->GetSign($signArr);
            return json_encode($signArr);
        }

        exit;


    }

    public function callback(&$recv){}

    /**
     * 以post方式提交xml到对应的接口url
     * @param bool $useCert 是否需要证书，默认不需要
     * @param int $second   url执行超时时间，默认30s
     * @throws Exception
     */
    public function PostXmlCurl()
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);

        curl_setopt($ch,CURLOPT_URL, self::UNIFIEDORDER);
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        if($this->useCert) {
            //使用证书：cert 与 key 分别属于两个.pem文件
            curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLCERT, self::SSLCERT_PATH);
            curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
            curl_setopt($ch, CURLOPT_SSLKEY, self::SSLKEY_PATH);
        }
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->ToXml());
        //运行curl
        $result = curl_exec($ch);
        //返回结果
        if($result){
            curl_close($ch);
            return $result;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            throw new HttpException("curl出错，错误码:$error");
        }
    }

    /**
     * 生成签名
     * @return 签名，本函数不覆盖sign成员变量，如要设置签名需要调用SetSign方法赋值
     */
    public function GetSign($fields)
    {
        $string = $this->ToUrlParams($fields);
        $string = $string . "&key=".self::KEY;
        $string = md5($string);
        $result = strtoupper($string);
        return $result;
    }

    /**
     *
     */
    public function ToUrlParams($fields){
        $buff = "";
        ksort($fields);
        $string = "";
        foreach ($fields as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $string .= $k . "=" . $v . "&";
            }

        }
        $string = trim($string, "&");
        return $string;
  }

    /**
     * 	作用：array转xml
     */
    public  function arrayToXml()
    {
        $xml = "<xml>";
        foreach ($this->fields as $key=>$val)
        {
            if (is_numeric($val))
            {
                $xml.="<".$key.">".$val."</".$key.">";

            }
            else
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
        $xml.="</xml>";
        return $xml;
    }

    /**
     * 	作用：将xml转为array
     */
    public function xmlToArray($xml)
    {
        //将XML转为array
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }


}